package com.shawbs.vueblog.comom.exception;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.shawbs.vueblog.comom.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.ShiroException;
import org.apache.shiro.authc.ExpiredCredentialsException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

/**
 * 全局异常处理
 */
@Slf4j
@ControllerAdvice
public class MyException {

    /**
     * shiro抛出的异常，比如没有权限，用户登录异常
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(ShiroException.class)
    public Result handle401(ShiroException e) {
        log.error("shiro异常:-------------->{}",e.getMessage());
        return Result.fail(401, e.getMessage());
    }


    @ResponseBody
    @ExceptionHandler(ExpiredCredentialsException.class)
    public Result handle401(ExpiredCredentialsException e) {
        log.error("令牌异常:-------------->{}",e.getMessage());
        return Result.fail(401, e.getMessage());
    }

    /**
     * 处理Assert的异常
     */
    @ResponseBody
    @ExceptionHandler(value = IllegalArgumentException.class)
    public Result handler(IllegalArgumentException e) throws IOException {
        log.error("Assert异常:-------------->{}",e.getMessage());
        return Result.fail(500,e.getMessage());
    }


    /**
     * post参数异常
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    public Result handleParamsError(HttpMessageNotReadableException e) {
        log.error("无参数异常：", e);
        return Result.fail(400, "参数异常");
    }


    @ResponseBody
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result handleParamsError(MethodArgumentNotValidException e) {
        log.error("参数检验异常：", e);
        BindingResult bindingResult = e.getBindingResult();
        ObjectError objectError = bindingResult.getAllErrors().stream().findFirst().get();
        return Result.fail(400, objectError.getDefaultMessage());
    }

    /**
     * get参数异常
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    public Result handleParamsError(MissingServletRequestParameterException e) {
        log.error("get参数异常：", e);
        return Result.fail(400, "参数异常");
    }


    @ResponseBody
    @ExceptionHandler(value = MybatisPlusException.class)
    public Result handleParamsError(MybatisPlusException e) {
        log.error("断言异常：", e);
        return Result.fail(400, e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(value = NullPointerException.class)
    public Result handleNullError(NullPointerException e) {
        log.error("空指针异常：", e);
        return Result.fail(500, "空指针异常");
    }

    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public Result handleError(Exception e) {
        log.error("未知异常：", e);
//        throw new Error(e);
        return Result.fail(500, "未知异常");
    }
}

